﻿using Blm.RabbitMQ.MessageQueue;
using Blm.RabbitMQ.Models;
using Blm.Utils.Extensions;
using Meta.RabbitMQ.Generic;
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Domain.DtoModel.Inner;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.DtoModel.RabbitMq;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Domain.Repository.Interface.Sys;
using VisionCloud.Service.Fms;
using VisionCloud.Service.Ms;

namespace VisionCloud.Web.Service.MQListener
{
    public class PushDeviceStatisticsBackgroundService : BlmRabbitMQStorageSubscriberBase<MsDevicePushDto>
    {
        private readonly ILogger<PushDeviceStatisticsBackgroundService> logger;
        private readonly ISysDeviceRepository sysDeviceRepository;
        private readonly ICSMSTaskRepository cSMSTaskRepository;
        private readonly ProjectDCService projectDCService;
        private readonly EfficiencyAnalyzeService efficiencyAnalyzeService;

        public PushDeviceStatisticsBackgroundService(IServiceProvider serviceProvider,
            ILogger<PushDeviceStatisticsBackgroundService> logger,
            ISysDeviceRepository sysDeviceRepository,
            ICSMSTaskRepository cSMSTaskRepository,
            ProjectDCService projectDCService,
            EfficiencyAnalyzeService efficiencyAnalyzeService) : base(serviceProvider)
        {
            this.logger = logger;
            this.sysDeviceRepository = sysDeviceRepository;
            this.cSMSTaskRepository = cSMSTaskRepository;
            this.projectDCService = projectDCService;
            this.efficiencyAnalyzeService = efficiencyAnalyzeService;
        }

        public override StorageWayEm StorageWay => StorageWayEm.OnlyStorage;

        public override ClientOption ClientOption => new ClientOption("push.device.ex", "push.device.rk", ExchangeType.Topic, "push.device.queue", RabbitMQConnectPoolName.CloudServerHost);

        /// <summary>
        /// 推送某个设备的累计测量面积、累计作业天数、设备状态到FMS
        /// </summary>
        /// <param name="model"></param>
        /// <returns></returns>
        public override async Task InvokeAsync(MsDevicePushDto model)
        {
            try
            {

                if (model == null || (model.Type == 1 && !model.DeviceId.HasValue) || model.Type == 2 && !model.ProjectId.HasValue)
                    throw new ArgumentNullException("队列消息内容为空");

                //设备id列表
                List<Guid> idList = new List<Guid>();
                //设备报告列表
                List<DeviceProjectPushDto> deviceTaskList = new List<DeviceProjectPushDto>();
                if (model.Type == 1)
                {
                    idList.Add(model.DeviceId.Value);
                    deviceTaskList = await cSMSTaskRepository.GetLastUploadTaskDeviceAsync(new List<Guid> { model.DeviceId.Value });
                }
                else if (model.Type == 2)
                {
                    var ids = await cSMSTaskRepository.GetProjectRelevanceDeviceAsync(model.ProjectId.Value);
                    if (ids != null && ids.Count > 0)
                    {
                        idList.AddRange(ids);
                        deviceTaskList = await cSMSTaskRepository.GetLastUploadTaskDeviceAsync(ids);
                    }
                }

                //推送列表
                var pushList = await efficiencyAnalyzeService.GetDeviceStitisticsStat(deviceTaskList, DateTime.MinValue, DateTime.Now);

                //设备列表
                var deviceList = await sysDeviceRepository.WhereAsNoTrackingAsync(p => idList.Contains(p.DeviceGuid) && !p.IsDeleted);
                if (deviceList == null || deviceList.Count == 0)
                {
                    throw new ArgumentNullException($"设备不存在");
                }

                foreach (var device in deviceList)
                {
                    var pl = pushList.FirstOrDefault(p => p.DeviceCode == device.DeviceNumber);
                    if (pl != null)
                    {
                        await projectDCService.PushDeviceStatistics(pl);
                    }
                    else
                    {
                        //设备不存在测量记录时，也要推送设备的状态到FMS
                        await projectDCService.PushDeviceStatistics(new DevicePushFMSDto
                        {
                            Active = device.IsActive,
                            DeviceCode = device.DeviceNumber,
                            TotalMeasureArea = 0,
                            TotalWorkingDuration = 0,
                            SoftwareVersion = device.DeviceSoftwareVersion,
                            UploadTime = device.LastUpdatedDate.ToDateTimeStandardString()
                        });
                    }
                }
            }
            catch (Exception ex)
            {
                logger.LogError($"PushDeviceStatisticsBackgroundService报错：{ex.Message}，{ex.StackTrace}，队列消息：{model?.ToJsonStr()}", ex);
            }
        }
    }
}
